#include "aodv_hello.h"
#include "aodv_packet.h"  // 使用aodv_packet.h中的build_hello_packet
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <pthread.h>
#endif

// 全局变量用于Hello定时器
static volatile int hello_timer_running = 0;
static SOCKET hello_sock = INVALID_SOCKET;
static uint32_t hello_local_ip = 0;
static uint32_t hello_broadcast_addr = 0;
static aodv_routing_table *hello_routing_table = NULL;

/**
 * 验证Hello消息的有效性
 */
int validate_hello_message(const aodv_hello *hello, size_t packet_size) {
    if (!hello) return 0;
    
    // 检查数据包大小
    if (packet_size < sizeof(aodv_hello)) {
        return 0;
    }
    
    // 检查消息类型
    if (hello->header.type != AODV_HELLO) {
        return 0;
    }
    
    // 检查生命周期
    if (hello->lifetime == 0 || hello->lifetime > 10000) { // 最大10秒
        return 0;
    }
    
    return 1;
}

/**
 * 处理接收到的Hello消息
 */
void process_hello_message(const aodv_hello *hello, uint32_t sender_addr, 
                        aodv_routing_table *routing_table, uint32_t local_ip) {
    if (!hello || !routing_table || sender_addr == local_ip) {
        return;
    }
    
    printf("Received HELLO from %s, lifetime: %u ms\n", 
           inet_ntoa(*(struct in_addr*)&sender_addr), hello->lifetime);
    
    // 查找发送者的路由条目
    routing_table_entry *route = routing_table_find(routing_table, sender_addr);
    
    if (route) {
        // 更新现有路由的生命周期
        route->lifetime = (uint32_t)time(NULL) + (hello->lifetime / 1000);
        printf("Updated route to %s, new lifetime: %u\n", 
               inet_ntoa(*(struct in_addr*)&sender_addr), route->lifetime);
    } else {
        // 创建新的路由条目（1跳邻居）
        routing_table_entry new_route = {
            .dest_addr = sender_addr,
            .dest_seq_num = 0, // Hello消息不包含序列号
            .next_hop_addr = sender_addr,
            .hop_count = 1,
            .lifetime = (uint32_t)time(NULL) + (hello->lifetime / 1000)
        };
        
        if (routing_table_add_or_update(routing_table, &new_route)) {
            printf("Added new route to neighbor %s (1 hop)\n", 
                   inet_ntoa(*(struct in_addr*)&sender_addr));
        }
    }
}

/**
 * 发送Hello消息
 */
void send_hello_message(SOCKET sock, uint32_t local_ip, uint32_t broadcast_addr) {
    if (sock == INVALID_SOCKET) return;
    
    aodv_hello hello_msg;
    build_hello_packet(&hello_msg, HELLO_LIFETIME_MS);
    
    // 构建完整的数据包
    uint8_t packet[sizeof(aodv_hello)];
    memcpy(packet, &hello_msg, sizeof(aodv_hello));
    
    // 设置广播地址
    struct sockaddr_in broadcast_sin;
    memset(&broadcast_sin, 0, sizeof(broadcast_sin));
    broadcast_sin.sin_family = AF_INET;
    broadcast_sin.sin_port = htons(AODV_PORT);
    broadcast_sin.sin_addr.s_addr = broadcast_addr;
    
    // 发送Hello消息
    int result = sendto(sock, (const char*)packet, sizeof(packet), 0,
                       (struct sockaddr*)&broadcast_sin, sizeof(broadcast_sin));
    
    if (result == SOCKET_ERROR) {
        int error = WSAGetLastError();
        printf("Failed to send HELLO message, error: %d\n", error);
    } else {
        printf("Sent HELLO message to broadcast address %s\n", 
               inet_ntoa(*(struct in_addr*)&broadcast_addr));
    }
}

/**
 * 检查邻居是否超时
 */
void check_neighbor_timeout(aodv_routing_table *routing_table, uint32_t local_ip, uint32_t current_time) {
    if (!routing_table) return;
    
    uint32_t current_time_sec = current_time; // 直接使用秒为单位的时间
    
    // 遍历路由表，检查1跳邻居是否超时
    // 注意：需要从后向前遍历，避免删除元素影响索引
    for (int i = routing_table->count - 1; i >= 0; i--) {
        routing_table_entry *entry = &routing_table->entries[i];
        
        // 只检查1跳邻居（跳数为1且下一跳等于目的地址）
        if (entry->hop_count == 1 && entry->next_hop_addr == entry->dest_addr) {
            if (entry->lifetime < current_time_sec) {
                printf("Neighbor %s timed out (lifetime: %u, current: %u)\n", 
                       inet_ntoa(*(struct in_addr*)&entry->dest_addr), 
                       entry->lifetime, current_time_sec);
                
                // 删除过期邻居路由
                routing_table_delete(routing_table, entry->dest_addr);
            }
        }
    }
}

/**
 * Hello定时器线程函数
 */
#ifdef _WIN32
static DWORD WINAPI hello_timer_thread(LPVOID lpParam) {
#else
static void* hello_timer_thread(void* arg) {
#endif
    while (hello_timer_running) {
        // 发送Hello消息
        if (hello_sock != INVALID_SOCKET) {
            send_hello_message(hello_sock, hello_local_ip, hello_broadcast_addr);
        }
        
        // 检查邻居超时
         // 检查邻居超时
         uint32_t current_time = (uint32_t)(time(NULL) * 1000); // 转换为毫秒
         check_neighbor_timeout(hello_routing_table, hello_local_ip, current_time);
        
        // 等待下一个周期
        Sleep(HELLO_INTERVAL_MS);
    }
    
#ifdef _WIN32
    return 0;
#else
    return NULL;
#endif
}

/**
 * 启动Hello定时器
 */
void start_hello_timer(SOCKET sock, uint32_t local_ip, uint32_t broadcast_addr, aodv_routing_table *routing_table) {
    if (hello_timer_running) {
        printf("Hello timer is already running\n");
        return;
    }
    
    hello_sock = sock;
    hello_local_ip = local_ip;
    hello_broadcast_addr = broadcast_addr;
    hello_routing_table = routing_table;
    hello_timer_running = 1;
    
#ifdef _WIN32
    HANDLE thread_handle = CreateThread(NULL, 0, hello_timer_thread, NULL, 0, NULL);
    if (thread_handle) {
        CloseHandle(thread_handle);
        printf("Hello timer started successfully\n");
    } else {
        printf("Failed to start Hello timer\n");
        hello_timer_running = 0;
    }
#else
    pthread_t thread;
    if (pthread_create(&thread, NULL, hello_timer_thread, NULL) == 0) {
        pthread_detach(thread);
        printf("Hello timer started successfully\n");
    } else {
        printf("Failed to start Hello timer\n");
        hello_timer_running = 0;
    }
#endif
}

/**
 * 停止Hello定时器
 */
void stop_hello_timer(void) {
    hello_timer_running = 0;
    printf("Hello timer stopped\n");
}